package com.za.apm.cat.config;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.dianping.cat.Cat;
import com.dianping.cat.Cat.Context;
import com.dianping.cat.message.Message;
import com.dianping.cat.message.Transaction;

/**
 * 类CatInterceptor.java的实现描述：
 * 
 * @author: tongyufu 2017-11-22 10:42:00
 */
public class CatInterceptor implements HandlerInterceptor {

	private ThreadLocal<Transaction> tranLocal = new ThreadLocal<Transaction>();
	private ThreadLocal<Transaction> pageLocal = new ThreadLocal<Transaction>();
	public static ThreadLocal<StringBuilder> logbackLocal = new ThreadLocal<>();
	Logger log = LoggerFactory.getLogger(CatInterceptor.class);

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		String uri = request.getRequestURI();
		Transaction t = Cat.newTransaction("MyURL", uri);
		Cat.logEvent("MyURL.Method", request.getMethod(), Message.SUCCESS, request.getRequestURL().toString());
		Cat.logEvent("MyURL.Host", request.getMethod(), Message.SUCCESS, request.getRemoteHost());
		tranLocal.set(t);
		logbackLocal.set(new StringBuilder());

		Cat.Context context = new CatContext();
		if (request.getHeader(Context.ROOT) == null) {
			Cat.logRemoteCallClient(context);
		} else {
			context.addProperty(Context.CHILD, request.getHeader(Context.CHILD));
			context.addProperty(Context.ROOT, request.getHeader(Context.ROOT));
			context.addProperty(Context.PARENT, request.getHeader(Context.PARENT));
			Cat.logRemoteCallServer(context);
		}
		request.setAttribute("_cat_context", context);

		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		String viewName = modelAndView != null ? modelAndView.getViewName() : "无";
		Transaction t = Cat.newTransaction("View", viewName);
		pageLocal.set(t);
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// 请求-页面渲染前
		Transaction pt = pageLocal.get();
		// 总计
		Transaction t = tranLocal.get();
		try {
			if (ex == null) {
				pt.setStatus(Transaction.SUCCESS);
				t.setStatus(Transaction.SUCCESS);
			} else {
				t.setStatus(ex);
				Cat.logError("===========错误============\n" + logbackLocal.get().toString(), ex);
				Cat.logError(ex);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			logbackLocal.remove();
			pageLocal.remove(); // need remove
			tranLocal.remove(); // need remove
			if (pt != null) {
				pt.complete();
			}
			t.complete();
		}
	}

}
